home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / 3dvect37.zip / 3D2.ASM < prev    next >
Assembly Source File  |  1994-06-22  |  35KB  |  1,172 lines

  1. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2. ;
  3. ; Filename     : 3d2.asm
  4. ; Included from: Main Assembley Module
  5. ; Description  : 3d vector routines full sorting method (slower)
  6. ;
  7. ; Written by: John McCarthy
  8. ;             1316 Redwood Lane
  9. ;             Pickering, Ontario.
  10. ;             Canada, Earth, Milky Way (for those out-of-towners)
  11. ;             L1X 1C5
  12. ;
  13. ; Internet/Usenet:  BRIAN.MCCARTHY@CANREM.COM
  14. ;         Fidonet:  Brian McCarthy 1:229/15
  15. ;   RIME/Relaynet: ->CRS
  16. ;
  17. ; Home phone, (905) 831-1944, don't call at 2 am eh!
  18. ;
  19. ; Send me your protected mode source code!
  20. ; Send me your Objects!
  21. ; But most of all, Send me a postcard!!!!
  22. ;
  23. ; - objects can pass through one another and still be sorted correctly
  24. ; - maxsurfs and maxpoints must be large - set to TOTAL points/surfs on screen
  25. ;
  26. ; To use:
  27. ;
  28. ;          call draw_landscape       ; draw background landscape
  29. ;          call clear_fill         ; clear video memory (last screen)
  30. ;          call look_at_it         ; make camera look at selected object
  31. ;          call setsincose         ; set rotation multipliers for eye
  32. ;          call show_stars         ; plot background stars (if you want)
  33. ;          call makeobjs           ; plot all objects in sides table
  34. ;          call instant_mouse      ; plot mouse on screen
  35. ;          call flip_page          ; flip video pages
  36. ;          call resetupd           ; reset update for borders
  37. ;          call updvectors         ; move objects around, rotate them
  38. ;
  39. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  40.  
  41.            .386p
  42.            jumps
  43.  
  44. code32     segment para public use32
  45.            assume cs:code32, ds:code32
  46.  
  47. ; define externals
  48.  
  49.            include pmode.ext       ; protected mode externals
  50.            include xmouse.ext      ; xmode mouse externals
  51.            include xmode.ext       ; xmode externals by matt pritchard
  52.            include irq.ext
  53.            include font.ext
  54.  
  55.            include macros.inc
  56.            include equ.inc
  57.  
  58.            include vars2.inc       ; labels and such
  59.            align 16
  60.            include arctan.inc      ; inverse tan
  61.            include sin.inc         ; sin/cosin table
  62.            include math.inc        ; rotate, cos,sin,arctan...
  63.            include xscale.inc
  64.            include poly.inc        ; common ploygon stuff
  65.            include more.inc        ; more common 3d/graphics stuff
  66.  
  67.            public makeobjs
  68.            public make1obj
  69.            public flush_surfaces
  70.            public init_tables
  71.  
  72.            strip_bytes equ 4
  73.  
  74.            align 16
  75.  
  76. abort_all:
  77.            add esp,strip_bytes    ; abort from loadpoints and make1obj
  78.            ret                    ; returning now from makeobjs call
  79.  
  80.            align 16
  81.  
  82. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  83. ; Loadpoints:  Begin loading of points from object definition data into array
  84. ; In:
  85. ;  ESI -> object #
  86. ; Out:
  87. ;  ESI -> offset of connection data
  88. ; Given ESI as object number.  rotate, translate and convert to 3d the points
  89. ; of that object.  returns edi as pointer to sides.
  90. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  91.  
  92. loadpoints:
  93.            mov bl,userotate[esi]  ; rotation type
  94.  
  95.            mov si,whatshape[esi*2] ; get shape
  96.            mov esi,objbase[esi*4]
  97.  
  98. view_is_not_ok:
  99.            mov eax,[esi]
  100.            add esi,8
  101.  
  102.            cmp eax,zad            ; check if too far to see detail anyway
  103.            jb s view_is_not_ok
  104.  
  105.            mov eax,[esi-4]
  106.            add esi,eax
  107. llkk:
  108.            movzx eax,w [esi]
  109.            mov numpoints,eax
  110.  
  111.            or eax,eax
  112.            jz no_points_anyway
  113.  
  114.            mov edi,pointindex     ; set xp,yp,zp pointer
  115.  
  116.            shl eax,2
  117.            add eax,pointindex     ; pointindex = word indexer to last point
  118.            cmp eax,maxpoints*4-4  ; test for overflow in points tables
  119.            jae abort_all
  120.  
  121.            mov ax,[esi+2]
  122.            mov numsides,eax
  123.  
  124.            add eax,showing
  125.            cmp eax,maxsurfaces-1  ; check for overflow in "sides" tables
  126.            jae abort_all
  127.  
  128.            add esi,4+25*2         ; skip point and side totals, skip future data
  129.            mov lindex,edi         ; set last index to points (this one)
  130.  
  131.            add edi,4              ; compensate for center of gravity point
  132. middle_load_points:
  133.            test bl,no_rotation    ; check userotate command
  134.            jnz np13               ; use different loop if no rotation
  135. np12:
  136.            movsx ebx,w [esi]      ; x
  137.            movsx ecx,w [esi+2]    ; y
  138.            movsx ebp,w [esi+4]    ; z
  139.  
  140.            push edi esi
  141.            call rotate            ; rotate based on object matrix
  142.            add ebp,zad
  143.  
  144.            cmp ebp,ztruncate
  145.            jge s ntrunct
  146.            neg ebp
  147.            cmp ebp,ztruncate
  148.            jge s ntrunct
  149.            mov ebp,ztruncate
  150. ntrunct:
  151.            add ebx,xad
  152.            add ecx,yad
  153.            call make3d
  154.            pop esi edi
  155.            mov xp[edi],ebx
  156.            mov yp[edi],ecx
  157.            mov zp[edi],ebp
  158.            add edi,4              ; inc xp indexer
  159.            add esi,6              ; inc input pointer
  160.            dec numpoints
  161.            jne s np12
  162.  
  163.            mov pointindex,edi     ; save for next call of loadpoints
  164.  
  165.            ret                    ; esi exits with pointer to sides
  166.  
  167. no_points_anyway:
  168.            mov ax,[esi+2]
  169.            mov numsides,eax
  170.  
  171.            add eax,showing
  172.            cmp eax,maxsurfaces-1  ; check for overflow in "sides" tables
  173.            jae abort_all
  174.  
  175.            add esi,4+25*2         ; skip point and side totals, skip future data
  176.  
  177.            mov edi,pointindex     ; set xp,yp,zp pointer
  178.            add pointindex,4
  179.            mov lindex,edi         ; set last index to points (this one)
  180.            ret
  181. np13:
  182.            movsx ebx,w [esi]      ; x
  183.            movsx ecx,w [esi+2]    ; y
  184.            movsx ebp,w [esi+4]    ; z
  185.  
  186.            push edi esi
  187.            call erotate           ; rotation matrix already set up! (camera)
  188.            add ebp,zad
  189.  
  190.            cmp ebp,ztruncate
  191.            jge s ntrunct2
  192.            neg ebp
  193.            cmp ebp,ztruncate
  194.            jge s ntrunct2
  195.            mov ebp,ztruncate
  196. ntrunct2:
  197.            add ebx,xad
  198.            add ecx,yad
  199.            call make3d
  200.            pop esi edi
  201.            mov xp[edi],ebx
  202.            mov yp[edi],ecx
  203.            mov zp[edi],ebp
  204.            add edi,4              ; inc xp indexer
  205.            add esi,6
  206.            dec numpoints
  207.            jne s np13
  208.  
  209.            mov pointindex,edi     ; save for next call of loadpoints
  210.  
  211.            ret
  212.  
  213.            align 16
  214.  
  215. special_commands dd offset dobitmap
  216.                  dd offset dobitmap
  217.                  dd offset pushmatrix
  218.                  dd offset popmatrix
  219.                  dd offset pushlocation
  220.                  dd offset poplocation
  221.                  dd offset newobject
  222.                  dd offset no_new_matrix
  223.                  dd offset gosub_function  ; 8
  224.                  dd offset return_function ; 9
  225.                  dd offset goto_function   ; 10
  226.  
  227. number_ofb dw 5*2
  228.            dw 5*2
  229.            dw 1*2
  230.            dw 1*2
  231.            dw 1*2
  232.            dw 1*2
  233.            dw 1*2
  234.            dw 1*2
  235.            dw ?   ; gosub_function
  236.            dw ?   ; return_function
  237.            dw ?   ; goto_function
  238.  
  239.            align 16
  240. gosub_function:
  241.            push esi
  242.            movsx eax,w [esi]
  243.            add esi,eax
  244.            jmp return_iteration
  245.  
  246.            align 16
  247. return_function:
  248.            pop esi
  249.            add esi,2
  250.            jmp return_iteration
  251.  
  252.            align 16
  253. goto_function:
  254.            movsx eax,w [esi]
  255.            add esi,eax
  256.            jmp return_iteration
  257.  
  258.            align 16
  259. pushmatrix:
  260.            push vmatrix+0
  261.            push vmatrix+4
  262.            push vmatrix+8
  263.            push vmatrix+12
  264.            push vmatrix+16
  265.            push vmatrix+20
  266.            push vmatrix+24
  267.            push vmatrix+28
  268.            push vmatrix+32
  269.            jmp return_iteration
  270.  
  271.            align 16
  272. popmatrix:
  273.            pop vmatrix+32
  274.            pop vmatrix+28
  275.            pop vmatrix+24
  276.            pop vmatrix+20
  277.            pop vmatrix+16
  278.            pop vmatrix+12
  279.            pop vmatrix+8
  280.            pop vmatrix+4
  281.            pop vmatrix+0
  282.            jmp return_iteration
  283.  
  284.            align 16
  285. pushlocation:
  286.            push xad
  287.            push yad
  288.            push zad
  289.            jmp return_iteration
  290.  
  291.            align 16
  292. poplocation:
  293.            pop zad
  294.            pop yad
  295.            pop xad
  296.            jmp return_iteration
  297.  
  298.            align 16
  299. ld_special:
  300.            mov cx,ax
  301.            and ecx,special-1      ; max 127 commands
  302.            jmp [special_commands+ecx*4]
  303.  
  304.            align 16
  305.  
  306. ; handle loading of bitmap from object list
  307. ;
  308. ; eg dw himap,8,5,50,60 ;command is 32,point 8, bitmap 5, x&y scaling of 50,60
  309.  
  310. dobitmap:
  311.            align 16
  312.  
  313.            lodsw                  ; get from si, first is point
  314.            shl eax,2
  315.            add eax,lindex         ; add to include offset in list
  316.            stosw                  ; put in sides table
  317.  
  318.            mov edx,ebp            ; save indexer
  319.            movzx ebp,ax           ; get point indexers
  320.            mov eax,zp[ebp]
  321.            mov zeds[ebx*2],eax    ; set zed for sort.
  322.            mov ebp,edx
  323.  
  324.            movsw                  ; get bitmap type
  325.            movsd                  ; get x then y scaling
  326.  
  327.            mov edx,command        ; get command (for iteration bits)
  328.            mov textures[ebx],dx
  329.  
  330.            cmp zad,64000          ; bitmaps farther than 65536 screw up
  331.            jge no_norml           ; you can't see them anyway. prevent overflow
  332.            jmp ln3
  333.  
  334.            align 16
  335.  
  336. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  337. ; Loadsides: Load connection data from object data definition
  338. ; In:
  339. ;  ESI -> offset of connection data
  340. ; Out: null
  341. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  342.  
  343. loadsides:
  344.            mov lamflag,no
  345.            mov edi,offsides       ; get ready for lodsw and stosw
  346.            mov ebp,edi            ; ebp = offset to first point in side
  347.            mov ebx,showing        ; bx = word indexer for surfaces
  348.            shl ebx,1
  349. ld_lp:
  350.            mov ax,[esi]           ; get command word
  351.            add esi,2
  352.            mov command,eax
  353.  
  354.            test eax,special       ; if bitmap, do special load,
  355.            jnz ld_special         ; or test previous color
  356.  
  357.            mov eax,[esi]          ; get texture data/type
  358.            mov texture12,eax
  359.  
  360.            mov eax,[esi+4]        ; get colour, high byte is other side
  361.            add esi,8
  362.            mov colors12,eax
  363.  
  364.            mov ecx,lindex         ; quick add for loop
  365.  
  366.            push ebp
  367.            push ebx
  368.  
  369.            movzx eax,w [esi]      ; get from esi, first is unconditinal
  370.            add esi,2
  371.            shl eax,2
  372.            add eax,ecx            ; add to include offset in list
  373.            mov [edi],ax           ; put in edi
  374.            add edi,2
  375.            mov edx,eax
  376. ld_loop:
  377.            lodsw                  ; get from esi
  378.            shl eax,2
  379.            add eax,ecx
  380.            mov [edi],ax           ; put in edi
  381.            cmp eax,edx            ; check all after first point
  382.            je s ld_exitloop
  383.  
  384.            lodsw
  385.            shl eax,2
  386.            add eax,ecx
  387.            mov [edi+2],ax
  388.            cmp eax,edx
  389.            je s ld_exitloop
  390.  
  391.            lodsw
  392.            shl eax,2
  393.            add eax,ecx
  394.            mov [edi+4],ax
  395.            cmp eax,edx
  396.            je s ld_exitloop
  397.  
  398.            lodsw
  399.            shl eax,2
  400.            add eax,ecx
  401.            mov [edi+6],ax
  402.            add edi,8
  403.            cmp eax,edx
  404.            jne s ld_loop
  405.  
  406. ld_exitloop:
  407.            push esi
  408.  
  409.            mov edi,ebp            ; adjust bp into appropriate indexer
  410.  
  411.            movzx ebp,w [edi+2]
  412.            mov ecx,[zp+ebp]
  413.            mov ebp,edx            ; get point indexers
  414.            add ecx,[zp+ebp]       ; take average of two z points for sort
  415.            mov zeds[ebx*2],ecx
  416.  
  417.            mov edx,command
  418.  
  419.            test edx,onscr         ; find if test is for on screen pixels
  420.            jnz test_if_on_screen
  421.            test dl,both           ; check if always visible
  422.            jnz its_line
  423.  
  424. return_screen:
  425.            mov edx,[xp+ebp]       ; first point
  426.            mov ebx,[yp+ebp]
  427.  
  428.            mov bp,[edi+2]
  429.            mov esi,[xp+ebp]       ; second point
  430.            mov ecx,[yp+ebp]
  431.  
  432.            mov bp,[edi+4]
  433.            mov edi,[xp+ebp]       ; third point
  434.            mov ebp,[yp+ebp]
  435.  
  436.            call checkfront        ; check if side is visable using p1,2,3
  437.  
  438.            pop esi ebx ebp        ; return object data pointer
  439.  
  440.            mov edx,command
  441.            or ecx,ecx
  442.            jle s test_shading     ; cx>-1 if side visible, skip if not
  443.            test edx,double        ; test to use other colour
  444.            jz s skipit            ; miss this side...
  445.            shr texture12,16
  446.            shr colors12,16
  447.            xor w texture12,inverse ; do inverse shading
  448. test_shading:
  449.            test texture12,shade+last
  450.            jnz handle_shading     ; shading bit set, do it...
  451. ln2:
  452.            test edx,check         ; find out if side is only a test side
  453.            jnz s no_show
  454.  
  455.            mov eax,texture12      ; another side added...
  456.            mov textures[ebx],ax
  457.            movzx eax,w colors12
  458.            add eax,palxrefx       ; get offset of palette cross reference table for this object
  459.            mov ax,[eax]
  460.            mov surfcolors[ebx],ax
  461. ln3:
  462.            inc showing            ; another side added...
  463.            add ebx,2
  464.            add ebp,maxpolys*2     ; bump ebp to next block
  465. no_show:
  466.            test edx,iterate
  467.            jnz handle_surface_iteration
  468. skipit:
  469.            test edx,normal        ; do we skip surface normal data
  470.            jz s no_norml
  471.            add esi,6
  472. no_norml:
  473.            test edx,iterate
  474.            jnz failed_iteration   ; skip iteration data if surface failure
  475.  
  476. return_iteration:
  477.            mov edi,ebp            ; set di for next stosw
  478.  
  479.            dec numsides           ; count for next side
  480.            jne ld_lp
  481.  
  482.            mov offsides,edi       ; save for next call
  483.  
  484.            ret
  485.  
  486.            align 16
  487. its_line:
  488.            pop esi ebx ebp
  489.            test w texture12,shade+last
  490.            jz ln2
  491.  
  492. ; handle gourad/lambert shading
  493.  
  494.            align 16
  495. handle_shading:
  496.            test w texture12,last  ; test to use previous colour or bitmap call
  497.            jnz ld_do_previous
  498.  
  499.            test w texture12,wavey
  500.            jnz ln2
  501.  
  502.            push ebx esi ebp edx
  503.  
  504.            cmp lamflag,no         ; is lambert matrix set up?
  505.            je s setitup           ; jump to less likely route
  506. returnq:
  507.            mov bx,word ptr [esi]  ; get surface normal
  508.            mov cx,word ptr [esi+2]
  509.            mov bp,word ptr [esi+4]
  510.            add esi,6
  511.            call lrotate           ; rotate surface normal by lambert matrix
  512.  
  513.            pop edx
  514.            test w texture12,inverse ; have the sides flipped? test dx,256
  515.            jnz s invert_colour    ; jump to least likely route
  516. lp_contin:
  517.            add edi,256
  518.            shr edi,1              ; result -256 to +256, turn into 0-256
  519.            mov al,b shading_tables[edi] ; now into 0-15
  520.            xor ah,ah
  521.  
  522.            pop ebp esi ebx
  523.  
  524.            add w colors12,ax      ; user can have offset color in object!
  525.  
  526.            jmp ln2
  527.  
  528.            align 16
  529. invert_colour:                    ; inversion occures with other side option,
  530.            neg edi                ; always visible option, and shading option
  531.            jmp lp_contin          ; all combined!
  532.  
  533.            align 16
  534. setitup:
  535.            push esi
  536.            mov esi,currobj        ; this is object # from make1obj
  537.            call lambert           ; set up lambert maxtrix
  538.            mov lamflag,yes
  539.            pop esi
  540.            jmp s returnq
  541.  
  542.            align 16
  543.  
  544. ld_do_previous:
  545.            mov ax,w colors12
  546.            mov cx,surfcolors[ebx-2]
  547.            and cx,shading_bits    ; drop old colour block, keep shading indexer (from math.inc)
  548.            add ecx,eax            ; add new colour block
  549.            mov w colors12,cx
  550.  
  551.            jmp ln2
  552.  
  553. ; handle iteration option
  554.  
  555.            align 16
  556.  
  557. handle_surface_iteration:
  558.            test edx,normal
  559.            jz s no_norml2
  560.            add esi,6              ; skip if shading normal present
  561. no_norml2:
  562.            test edx,matrix        ; test to derive new matrix
  563.            jz no_new_matrix
  564. newobject:
  565.            mov edi,currobj        ; new matrix, get offset object number
  566.            add di,[esi+16]
  567.            test onoff[edi],sub_object_on ; test if sub-object has been turned on...
  568.            jz failed_iteration
  569.  
  570.            mov eax,[esi+24]
  571.            mov minzc,eax
  572.            mov eax,[esi+28]
  573.            mov btolr,eax
  574.            push ebx esi ebp edx   ; save stuff before iteration handle
  575.  
  576.            mov bx,w xs[edi*4]     ; get rotation location
  577.            mov cx,w ys[edi*4]
  578.            mov bp,w zs[edi*4]
  579.            add bx,[esi+10]
  580.            add cx,[esi+12]
  581.            add bp,[esi+14]
  582.            movsx ebx,bx
  583.            movsx ecx,cx
  584.            movsx ebp,bp
  585.  
  586.            push edi
  587.            call rotate            ; z<>0, find rotation location
  588.  
  589.            add xad,ebx
  590.            add yad,ecx
  591.            add zad,ebp
  592.  
  593.            pop esi                ; return object number+offset
  594.            test userotate[esi],no_rotation ; test to use new matrix or add to old
  595.            jnz do_compound_thingy
  596.            call temp_matrix       ; add to old
  597.            call matrix_multiply
  598.            mov eax,minzc
  599.            cmp zad,eax            ; check if new object will be behind camera
  600.            jg done_alterq
  601.            jmp failed_iterationq
  602.  
  603. do_compound_thingy:
  604.            call compound          ; compound new matrix
  605.            mov eax,minzc
  606.            cmp zad,eax            ; check if new object will be behind camera
  607.            jg done_alterq
  608.            jmp failed_iterationq
  609.  
  610. no_new_matrix:
  611.            test b [esi+8],centroid ; is there a centroid offset?
  612.            jz done_alter
  613.            mov eax,[esi+28]
  614.            mov btolr,eax
  615.  
  616.            push ebx esi ebp edx   ; save stuff before centroid handle
  617.            movsx ebx,w [esi+10]   ; no new matrix command, find point
  618.            movsx ecx,w [esi+12]   ; offset (addition)
  619.            movsx ebp,w [esi+14]
  620.  
  621.            call rotate            ; if found, add rotated point to xad,yad,zad
  622.  
  623.            add xad,ebx
  624.            add yad,ecx
  625.            add zad,ebp
  626.  
  627. done_alterq:
  628.            sub zad,1
  629.            adc zad,1
  630.  
  631.            mov ebx,xad            ; test if new xad,yad,zad are within screen boundaries
  632.            mov ecx,yad
  633.            mov ebp,zad
  634.  
  635.            cmul eax,ebx,ratiox    ; use fast constant multiply fo 3d conversion
  636.            idiv ebp
  637.  
  638.            movsx edx,xmins
  639.            sub edx,btolr
  640.            cmp eax,edx            ; tolerance is max object size/ratio
  641.            jl failed_iterationq
  642.            movsx edx,xmaxs
  643.            add edx,btolr
  644.            cmp eax,edx
  645.            jge failed_iterationq
  646.  
  647.            mov ebx,eax
  648.  
  649.            cmul eax,ecx,ratioy
  650.            idiv ebp
  651.  
  652.            movsx edx,ymins
  653.            sub edx,btolr
  654.            cmp eax,edx
  655.            jl failed_iterationq
  656.            movsx edx,ymaxs
  657.            add edx,btolr
  658.            cmp eax,edx
  659.            jge failed_iterationq
  660.  
  661.            mov edi,pointindex
  662.            mov xp[edi],ebx
  663.            mov yp[edi],eax
  664.            mov zp[edi],ebp
  665.            add pointindex,4
  666.  
  667.            pop edx ebp esi ebx
  668.  
  669. done_alter:
  670.            movzx eax,w [esi]      ; get number of extra points in iteration
  671.            add esi,2
  672.            mov numpoints,eax      ; set as counter
  673.            mov ecx,eax            ; save number of extra points for later use
  674.  
  675.            shl eax,2
  676.            add eax,pointindex     ; pointindex = word indexer to last point
  677.            cmp eax,maxpoints*4    ; test for overflow in points tables
  678.            jae abort_all2
  679.  
  680.            lodsw                  ; get number of sides in iteration
  681.            add numsides,eax
  682.  
  683.            add eax,showing
  684.            cmp eax,maxsurfaces-1  ; check for overflow in "sides" tables
  685.            jae abort_all2
  686.  
  687.            add esi,25*2
  688.  
  689.            or ecx,ecx             ; no new points to add? (just surfaces)
  690.            je return_iteration    ; only sides added to iteration, done...
  691.  
  692.            push ebx ebp edx       ; save load and store locations
  693.  
  694.            mov edi,currobj        ; add more points to xp,yp,zp list
  695.            mov bl,userotate[edi]  ; because iteration is visible
  696.  
  697.            mov edi,pointindex     ; movzx edi,pointindex
  698.  
  699.            call middle_load_points
  700.            pop edx ebp ebx
  701.  
  702.            jmp return_iteration
  703.  
  704.            align 16
  705.  
  706. abort_all2:
  707.            add esp,strip_bytes    ; abort from iteration and make1obj
  708.            ret                    ; returning now from makeobjs call
  709.  
  710. ; perform test for option 1024 - generate iteration if points on screen.
  711. ; routine also tests if polygon crosses screen - eg no point is on the screen
  712. ; but the polygon covers the screen, like the front of a very big building.
  713.  
  714.            align 16
  715.  
  716. test_if_on_screen:
  717.            xor bl,bl              ; bl = quadrant flag
  718.            push edx edi           ; save command
  719.  
  720.            mov esi,ebp
  721. tios:
  722.            mov ecx,xp[esi]        ; cx, dx =(x,y) to test
  723.            mov edx,yp[esi]
  724.  
  725.            mov ah,32              ;  32 16  8    determine where point is,
  726.            cmp cx,xmins           ;1  x  x  x    then or bl with location
  727.            jl s ytest             ;2  x  x  x
  728.            mov ah,8               ;4  x  x  x
  729.            cmp cx,xmaxs           ;
  730.            jge s ytest
  731.            mov ah,16
  732. ytest:
  733.            mov al,1
  734.            cmp dx,ymins
  735.            jl s oritall
  736.            mov al,4
  737.            cmp dx,ymaxs
  738.            jge s oritall
  739.  
  740.            cmp ah,16
  741.            je s on_screen         ; a point is on the screen, generate side...
  742. oritall:
  743.            or bl,ah               ; point is not on the screen, but it may
  744.            or bl,al               ; contribute to a polygon which covers the screen.
  745.  
  746.            add edi,2              ; get next connection for another test
  747.            mov si,sides[edi]
  748.            cmp si,bp              ; test if at last connection in iteration test
  749.            jne tios
  750.  
  751.            xor al,al              ; count number of bits in y (must be >2)
  752.            ror bl,1
  753.            adc al,0
  754.            ror bl,1
  755.            adc al,0
  756.            ror bl,1
  757.            adc al,0
  758.            cmp al,1
  759.            jbe s skipit2
  760.  
  761.            xor al,al              ; now count x (must be >2)
  762.            ror bl,1
  763.            adc al,0
  764.            ror bl,1
  765.            adc al,0
  766.            ror bl,1
  767.            adc al,0
  768.            cmp al,1
  769.            jbe s skipit2
  770. on_screen:
  771.            pop edi edx
  772.  
  773.            test edx,both          ; side is on screen
  774.            jz return_screen       ; test if alway visible
  775.  
  776.            pop esi ebx ebp        ; always, pop and test for shading
  777.            test edx,shade
  778.            jz ln2                 ; no shading - do normal return
  779.            jmp handle_shading
  780.  
  781. skipit2:
  782.            pop edi edx esi ebx ebp
  783.            jmp skipit
  784.  
  785. ; handle failure of option 512
  786.  
  787.            align 16
  788.  
  789. failed_iterationq:
  790.            pop edx ebp esi ebx
  791.  
  792. failed_iteration:
  793.            movzx ecx,w [esi+4]    ; number of bytes to skip in case of failure
  794.            mov ax,[esi+6]         ; get number of points TOTAL in iteration
  795.            add esi,8
  796.            shl eax,2              ; in case iteration in iteration in iteration...
  797.            add w pointindex,ax
  798.            add esi,ecx
  799.            jmp return_iteration
  800.  
  801.            align 16
  802.  
  803. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  804. ; Make1obj: Handle plotting of object ESI
  805. ; In:
  806. ;   ESI -> object #
  807. ; OUT:null
  808. ; Notes:
  809. ; Routine assumes object is already ON!  note: esi not si!
  810. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  811.  
  812. make1obj:
  813.            mov currobj,esi
  814.  
  815.            mov ebx,xs[esi*4]      ; displacement
  816.            sub ebx,eyex
  817.            mov ecx,ys[esi*4]
  818.            sub ecx,eyey
  819.            mov ebp,zs[esi*4]
  820.            sub ebp,eyez
  821.  
  822.            test userotate[esi],s_himap+s_point ; check if bitmap or point
  823.            jnz mo_special
  824.  
  825.            shr ebx,8              ; account for decimal places
  826.            test ebx,00800000h
  827.            jz s pm_1
  828.            or ebx, 0ff000000h
  829. pm_1:
  830.            shr ecx,8
  831.            test ecx,00800000h
  832.            jz s pm_2
  833.            or ecx, 0ff000000h
  834. pm_2:
  835.            shr ebp,8
  836.            test ebp,00800000h
  837.            jz s pm_3
  838.            or ebp, 0ff000000h
  839. pm_3:
  840.            mov si,whatshape[esi*2] ; get shape
  841.            mov esi,objbase[esi*4] ; get header start
  842.            add esi,[esi+4]        ; get first resolution
  843.            mov edi,[esi+14*2]     ; get maximum distance seen
  844.  
  845.            cmp ebx,edi            ; check if within visible space
  846.            jnl s noa2             ; if object miles away, don't bother
  847.            cmp ebp,edi
  848.            jnl s noa2
  849.            cmp ecx,edi
  850.            jnl s noa2
  851.            neg edi
  852.            cmp ebp,edi
  853.            jl s noa2
  854.            cmp ebx,edi
  855.            jl s noa2
  856.            cmp ecx,edi
  857.            jg s mo_misout
  858. noa2:
  859.            ret
  860. mo_misout:
  861.            mov edi,dword ptr [esi+16*2]
  862.            mov eax,dword ptr [esi+18*2]
  863.            mov btolr,eax
  864.            call zsolve            ; figure out camera displacement
  865.  
  866.            cmp esi,edi            ; check if behind camera, miminum dist.
  867.            jl s noa2
  868.  
  869.            sub esi,1              ; make z non-zero
  870.            adc esi,1
  871.  
  872.            call xsolve
  873.            mov xad,edi            ; store 3d offsets
  874.            call make3dx           ; now make object farther in 3d
  875.  
  876.            movsx eax,xmins
  877.            sub eax,btolr
  878.            cmp edi,eax            ; tolerance is max object size/ratio
  879.            jl s noa2
  880.            movsx eax,xmaxs
  881.            add eax,btolr
  882.            cmp edi,eax
  883.            jge s noa2
  884.  
  885.            call ysolve            ; solve y and set correct regs
  886.            mov yad,ecx
  887.            call make3dy           ; now make object farther in 3d
  888.  
  889.            movsx eax,ymins
  890.            sub eax,btolr
  891.            cmp ecx,eax
  892.            jl s noa2
  893.            movsx eax,ymaxs
  894.            add eax,btolr
  895.            cmp ecx,eax
  896.            jge s noa2
  897.  
  898.            mov zad,ebp
  899.            mov esi,pointindex
  900.  
  901.            mov xp[esi],ebx        ; save center of gravity as point 0
  902.            mov yp[esi],ecx
  903.            mov zp[esi],ebp
  904.  
  905.            mov esi,currobj        ; pop original object number
  906.            xor ebx,ebx
  907.            mov bl,palxref[esi]
  908.            mov ebx,xreftable[ebx*4]
  909.            mov palxrefx,ebx
  910.  
  911.            test userotate[esi],no_rotation ; test to call compound routine
  912.            jnz s mk_skipc         ; skip if anything other than full rotations
  913.            call compound          ; full rotation object, calc. matrix
  914. mk_skipc:
  915.            call loadpoints        ; load points and rotate, exit di=sides
  916.            jmp  loadsides         ; now load sides, starting at di
  917.  
  918.            align 16
  919. noa:
  920.            ret
  921.  
  922.            align 16
  923.  
  924. ; if userotate = 32 then draw bitmap at location x,y,z
  925.  
  926. mo_special:
  927.            mov edi,maxz*256
  928.            cmp ebx,edi            ; check if within visible space
  929.            jnl s noa              ; if object miles away, don't bother
  930.            cmp ebp,edi
  931.            jnl s noa
  932.            cmp ecx,edi
  933.            jnl s noa
  934.            neg edi
  935.            cmp ebp,edi
  936.            jl s noa
  937.            cmp ebx,edi
  938.            jl s noa
  939.            cmp ecx,edi
  940.            jl s noa
  941.  
  942.            shr ebx,8              ; account for decimal places, /256
  943.            test ebx,00800000h
  944.            jz s pq_1
  945.            or ebx, 0ff000000h
  946. pq_1:
  947.            shr ecx,8
  948.            test ecx,00800000h
  949.            jz s pq_2
  950.            or ecx, 0ff000000h
  951. pq_2:
  952.            shr ebp,8
  953.            test ebp,00800000h
  954.            jz s pq_3
  955.            or ebp, 0ff000000h
  956. pq_3:
  957.  
  958.            call zsolve            ; figure out camera displacement
  959.  
  960.            cmp esi,minz           ; check if behind camera, miminum dist.
  961.            jl noa
  962.  
  963.            call xsolve
  964.            mov xad,edi            ; store 3d offsets
  965.            call make3dx           ; now make object farther in 3d
  966.  
  967.            cmp edi,xmit           ; tolerance is max object size/ratio
  968.            jl noa
  969.            cmp edi,xmat
  970.            jge noa
  971.  
  972.            call ysolve            ; solve y and set correct regs
  973.            mov yad,ecx
  974.            call make3dy           ; now make object farther in 3d
  975.  
  976.            cmp ecx,ymit
  977.            jl noa
  978.            cmp ecx,ymat
  979.            jge noa
  980.  
  981.            mov zad,ebp
  982.            mov esi,currobj        ; pop original object number
  983.  
  984.            cmp pointindex,(maxpoints-1)*2 ; check if there is room in table
  985.            jge noa
  986.            cmp showing,maxsurfaces-1
  987.            jge noa
  988.  
  989.            test userotate[esi],s_point ; is point or bitmap?
  990.            jnz mo_ispoint
  991.  
  992.           ;cmp ebp,65535          ; far bitmaps screw up, abort
  993.           ;jge noa
  994.  
  995.            mov edi,pointindex
  996.            mov [xp+edi],ebx       ; set location of bitmap
  997.            mov [yp+edi],ecx
  998.            mov [zp+edi],ebp
  999.  
  1000.            mov edi,offsides
  1001.            add offsides,maxpolys*2 ; update for next object/bitmap
  1002.  
  1003.            mov ebx,showing
  1004.            shl ebp,1              ; adjust so it's the same as loadsides
  1005.            mov zeds[ebx*4],ebp    ; set z sort indexer
  1006.  
  1007.            inc showing            ; one more surface...
  1008.            xor ah,ah
  1009.            mov al,userotate[esi]
  1010.            mov textures[ebx*2],ax ; set command for bitmap
  1011.  
  1012.            mov eax,pointindex
  1013.            add pointindex,4
  1014.            stosw
  1015.            mov ax,whatshape[esi*2]
  1016.            stosw
  1017.            mov ax,vxs[esi*2]      ; set x and y scales (stretching)
  1018.            stosw
  1019.            mov ax,vys[esi*2]
  1020.            stosw
  1021. noa4:
  1022.            ret
  1023.  
  1024.            align 16
  1025.  
  1026. mo_ispoint:
  1027.            cmp bx,xmins            ; draw single point/bullet
  1028.            jl s noa4
  1029.            cmp bx,xmaxs
  1030.            jge s noa4
  1031.            cmp cx,ymins
  1032.            jl s noa4
  1033.            cmp cx,ymaxs            ; ymaxs1 if larger pixel
  1034.            jge s noa4
  1035.  
  1036.            mov edi,pointindex
  1037.            mov [xp+edi],ebx        ; set location of point/bitmap
  1038.            mov [yp+edi],ecx
  1039.            mov [zp+edi],ebp
  1040.  
  1041.            mov edi,offsides
  1042.            add offsides,maxpolys*2 ; update for next object/bitmap
  1043.  
  1044.            mov ebx,showing
  1045.            shl ebx,1
  1046.            shl ebp,1
  1047.            mov zeds[ebx*2],ebp    ; set z sort indexer
  1048.  
  1049.            inc showing            ; one more surface...
  1050.  
  1051.            mov textures[ebx],64   ; set this command as point
  1052.            mov surfcolors[ebx],bulletcolour ; only for variable colours
  1053.  
  1054.            mov eax,pointindex
  1055.            add pointindex,4
  1056.  
  1057.            stosw
  1058.            stosw
  1059. noa8:
  1060.            ret
  1061.  
  1062.            align 16
  1063.  
  1064. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1065. ; Set_order: Initialize original order for plotting objects
  1066. ;  In=Out=null
  1067. ; Notes:  This is called by Flush_surfaces so no need for you to do it.
  1068. ; This must be called every frame to re-initalize the order for polygon sorting
  1069. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1070.  
  1071. set_order:
  1072.            mov ecx,showing
  1073.            jcxz s non2_do
  1074.            dec ecx
  1075.            jz s non2_do
  1076.            shl ecx,1
  1077.            mov esi,ecx
  1078.            shl esi,1
  1079.            add esi,offset order
  1080.  
  1081.            prc equ 8
  1082.  
  1083.            cmp ecx,prc*2
  1084.            jb s ordrloop
  1085. bigsloop:
  1086.            i=0
  1087.            rept prc
  1088.            mov [esi+i],ecx
  1089.            i=i-4
  1090.            sub ecx,2
  1091.            endm
  1092.            jz s non2_do
  1093.            sub esi,prc*4
  1094.            cmp ecx,prc*2
  1095.            jae s bigsloop
  1096. ordrloop:
  1097.            mov [esi],ecx
  1098.            sub esi,4
  1099.            dec ecx
  1100.            loop ordrloop
  1101. non2_do:
  1102.            mov [order],0           ; fill last
  1103.  
  1104.            ret
  1105.  
  1106.            align 16
  1107.  
  1108. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1109. ; Makeobjs: Make/plot all objects on current_page, unrolled loop
  1110. ;  In=Out=null
  1111. ; Notes: Called from makeobjs
  1112. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1113.  
  1114. makeobjx:
  1115.            i=1
  1116.  
  1117.            rept maxobjects
  1118.            local itsoff
  1119.  
  1120.            test onoff+i,mainobject_on ; check on/off
  1121.            jz s itsoff
  1122.  
  1123.            mov esi,i
  1124.            call make1obj
  1125. itsoff:
  1126.  
  1127.            i=i+1
  1128.            endm
  1129.  
  1130.            ret                     ; put no code here! make1obj may force abort!
  1131.  
  1132. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1133. ; Init_tables: Initialize ordering before beginning 3d animation
  1134. ;  In=Out=null
  1135. ; Notes: Called by YOU. Different routines between 3d1,3d2 and 3d3
  1136. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1137.  
  1138. init_tables:
  1139.            mov offsides, offset sides ; clear table indexers for call
  1140.            mov pointindex,0
  1141.            mov showing,0
  1142.            ret
  1143.  
  1144.            align 16
  1145.  
  1146. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1147. ; Makeobjs: Make/plot all objects on current_page
  1148. ;  In=Out=null
  1149. ; Notes: Called from your mainline animation routine, falls through to flush_surfaces
  1150. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1151. makeobjs:
  1152.            call makeobjx          ; make objects
  1153.  
  1154. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1155. ; Flush_surfaces: Sort and flush all surfaces from polygon buffer to screen
  1156. ;  In=Out=null
  1157. ; Notes: called by makeobjs
  1158. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1159.  
  1160. flush_surfaces:
  1161.            call set_order         ; set ordering of sides
  1162.            call sort_list         ; sort sides according to z distance
  1163.            call drawvect          ; draw 'em on da screen
  1164.  
  1165.            mov offsides, offset sides ; clear table indexers for call
  1166.            mov pointindex,0
  1167.  
  1168.            ret
  1169.  
  1170. code32     ends
  1171.            end
  1172.